
using System;
using System.IO;
using System.Linq;


/**
* 只搬 public 和 private 文件夹下的
* 在搬运 public 下的.h 文件会进行 宏替换
*/
public class MovingCodeToNewProj
{

  public static void Exec(UeProjPojo new_proj_info, UeProjPojo rp_proj_info)
  {

    var task = BuildTask(new_proj_info, rp_proj_info);
    // 检查新工程路径中是否存在重名与需要搬迁工程的文件
    if (task.IsToPathExists()) throw new UePTException(Error.Err_2);
    try
    {
      // 先复制Private到目的地
      task.PrivatefilesFor(CopyFile);
      // 然后复制Public，并且替换宏
      task.PublicfilesFor(task =>
      {
        CopyAndReplaceMacro(new_proj_info.macroName, rp_proj_info.macroName, task);
      });
    }
    catch (Exception)
    {
      throw new UePTException(Error.Err_6);
    }
  }

  private static void CopyFile(TaskPojo task)
  {
    Directory.CreateDirectory(Path.GetDirectoryName(task.toFp));
    File.Copy(task.fromFp, task.toFp, true);
  }

  public static void CopyAndReplaceMacro(string toMacro, string fromMacro, TaskPojo task)
  {
    Directory.CreateDirectory(Path.GetDirectoryName(task.toFp));
    // 读取源文件内容
    string fileContent;
    using (StreamReader reader = new StreamReader(task.fromFp))
    {
      fileContent = reader.ReadToEnd();
    }
    string f_macro = $"class {fromMacro} ";
    string to_macro = $"class {toMacro} ";
    fileContent = fileContent.Replace(f_macro, to_macro);

    using (StreamWriter writer = new StreamWriter(task.toFp))
    {
      writer.Write(fileContent);
    }
  }

  private static MovingCodeTaskPojo BuildTask(UeProjPojo new_proj_info, UeProjPojo rp_proj_info)
  {
    TaskPojo[] public_files;
    // 获取需要移动的全部文件名
    if (Directory.Exists(rp_proj_info.projectSourcePublicPath))
    {
      public_files = Directory.GetFiles(rp_proj_info.projectSourcePublicPath, "*.*", SearchOption.AllDirectories)
      .Select(path => new TaskPojo(path, path.Replace(rp_proj_info.projectSourcePublicPath, new_proj_info.projectSourcePublicPath)))
      .ToArray();
    }
    else
    {
      public_files = Directory.GetFiles(rp_proj_info.sourcePublicPath, "*.*", SearchOption.AllDirectories)
      .Select(path => new TaskPojo(path, path.Replace(rp_proj_info.sourcePublicPath, new_proj_info.projectSourcePublicPath)))
      .ToArray();
    }

    TaskPojo[] private_files;
    if (Directory.Exists(rp_proj_info.projectSourcePrivatePath))
    {
      private_files = Directory.GetFiles(rp_proj_info.projectSourcePrivatePath, "*.*", SearchOption.AllDirectories)
      .Select(path => new TaskPojo(path, path.Replace(rp_proj_info.projectSourcePrivatePath, new_proj_info.projectSourcePrivatePath)))
      .ToArray();
    }
    else
    {
      private_files = Directory.GetFiles(rp_proj_info.sourcePrivatePath, "*.*", SearchOption.AllDirectories)
      .Select(path => new TaskPojo(path, path.Replace(rp_proj_info.sourcePrivatePath, new_proj_info.projectSourcePrivatePath)))
     .ToArray();
    }

    var task = new MovingCodeTaskPojo(public_files, private_files);

    return task;
  }

}
